#include<linux/module.h>
#include<linux/sched.h>
#include<linux/list.h>
#include<linux/wait.h>
#include<linux/kthread.h>
MODULE_LICENSE("GPL");

wait_queue_head_t head;
wait_queue_t data;

int my_function(void *argc)
{
	int wait_queue_num=0,return_data;
	wait_queue_t *curr,*next;
	printk("in the kernel thread function!\n");
	list_for_each_entry_safe(curr,next,&(head.task_list),task_list)
	{
		wait_queue_num++;	
		printk("the pid value of the current data of the waitqueue is:%d\n",
				((struct task_struct *)(curr->private))->pid);
		printk("the state of the current data of the waitqueue is:%ld\n",
				((struct task_struct *)(curr->private))->state);
	}
	printk("the value of the wait_queue_num is :%d\n",wait_queue_num);

	return_data=autoremove_wake_function(&data,TASK_NORMAL,1,NULL);

	wait_queue_num=0;

	list_for_each_entry_safe(curr,next,&(head.task_list),task_list)
	{
		wait_queue_num++;	
		printk("the pid value of the current data of the waitqueue is:%d\n",
				((struct task_struct *)(curr->private))->pid);
		printk("the state of the current data of the waitqueue is:%ld\n",
				((struct task_struct *)(curr->private))->state);
	}

	printk("the value os the wait_queue_num is:%d\n",wait_queue_num);

	printk("the return_data of the autoremove_wake_function is:%d\n",return_data);
	printk("the current pid is:%d\n",current->pid);
	printk("out the kernel thread function\n");
	return 0;
}

static int __init autoremove_wake_function_init(void)
{
	char namefrm[]="add_wait_queue.c";
	struct task_struct *result;
	int result1=-2,wait_queue_num=0,left_time;
	wait_queue_t *curr,*next;

	printk("into autoremove_wake_function_init.\n");
	result=kthread_create_on_node(my_function,NULL,-1,namefrm);

	init_waitqueue_head(&head);
	init_waitqueue_entry(&data,current);
	add_wait_queue(&head,&data);

	left_time=schedule_timeout_uninterruptible(1000);
	if(data.private !=NULL)
	{
		result1=autoremove_wake_function(&data,TASK_ALL,0,NULL);	
	}


	list_for_each_entry_safe(curr,next,&(head.task_list),task_list)
	{
		wait_queue_num++;	
		printk("the pid value of the current data of the waitqueue is:%d\n",
				((struct task_struct *)(curr->private))->pid);
		printk("the state if the current data of the waitqueue is:%ld\n",
				((struct task_struct *)(curr->private))->state);
	}
	printk("the letf time of the sleep_on_timeout is:%d\n",left_time);

	printk("the return result of the autoremove_wake_function is:%d\n",result1);

	printk("the pid of the wait_queue_num is:%d\n",wait_queue_num);

	printk("the pid os the kthread_create_on_node is:%d\n",result->pid);

	printk("the current pid is:%d\n",current->pid);
	printk("out autoremove_wake_function_init.\n");
	return 0;
}
static void __exit autoremove_wake_function_exit(void)
{
	printk("Goodbye autoremove_wake_function\n");
}
module_init(autoremove_wake_function_init);
module_exit(autoremove_wake_function_exit);
